import { ObjHandle } from "../Framework/ObjHandle";
import { L2VMessageEnum } from "../Framework/Network/L2VMessageEnum";
import tileBtn from "../Input/tileBtn";

const {ccclass, property} = cc._decorator;
const LINE_HEIGHT:number = 135;
const LINE_NUM: number = 7;
const FIRST_DROP_HEIGHT:number = LINE_HEIGHT * LINE_NUM;
const DROP_SPEED: number = 0.2;


@ccclass
export class VisualEntity extends cc.Component {

    entityID: number;
    characterID: number;

    self:ObjHandle<VisualEntity> = ObjHandle.NULL;

    msgDispatcher: {[key:number]: ((restParam: any[]) => void)[]} = {}

    x:number;
    y:number;

    createFirst:boolean;
    targetPosition:cc.Vec2;
    dropTime: number;
    dropSpeed: number;

    numLabel: cc.Label;
    

    init(): void
    {
        this.createFirst = true;
        this.dropTime = 0;
        let numNode = this.node.getChildByName("num");
        if(numNode != null)
            this.numLabel = numNode.getComponent(cc.Label);
        else
            this.numLabel = null;
        this.registerMsg(L2VMessageEnum.OnTileSetPosition, this.onSetPosition);
        this.registerMsg(L2VMessageEnum.OnTileNumber, this.onSetNumber);

        this.SetNumber(0);
    }

    onDestroy(): void
    {
        this.unregisterMsg(L2VMessageEnum.OnTileSetPosition, this.onSetPosition);
        this.unregisterMsg(L2VMessageEnum.OnTileNumber, this.onSetNumber);
    }  

    tick(dt): void
    {
        if(this.dropTime > 0)
        {
            let position = this.node.position;
            position.y -= dt * this.dropSpeed;
            this.node.position = position;
            this.dropTime -= dt;
            if(this.dropTime <= 0)
            {
                tileBtn.movingTileNum -= 1;
                this.node.position = this.targetPosition;
            }
        }
    }

    registerMsg(msgID: L2VMessageEnum, handler: (restParam: any[]) => void): void
    {
        let msgHandler = this.msgDispatcher[msgID];
        if(msgHandler == undefined)
        {
            this.msgDispatcher[msgID] = [handler];
        }
        else
        {
            msgHandler.push(handler);
        }
    }

    unregisterMsg(msgID: L2VMessageEnum, handler: (restParam: any[]) => void): void
    {
        let msgHandler = this.msgDispatcher[msgID];
        if(msgHandler != undefined)
        {
            for(let i = 0; i < msgHandler.length; i++)
            {
                if(msgHandler[i] == handler)
                {
                    msgHandler[i] = null;
                }
            }
        }
    }

    dispatchMsg(msgID: L2VMessageEnum, restParam: any[]): void
    {
        let msgHandler = this.msgDispatcher[msgID];
        if(msgHandler != undefined)
        {
            for(let i = 0; i < msgHandler.length; i++)
            {
                
                if(msgHandler[i] != null)
                {
                    msgHandler[i](restParam);
                }
            }
        }
    }

    onSetPosition = (param: any[]) =>
    {
        let x = param[2]; let y = param[3]; let drop = param[4];
        this.x = x; this.y = y;
        let index = 8 * y + x;
        let pos = cc.find("Canvas/playbg").children[index].position;
        if(this.createFirst)
        {
            let firstDropPosition = new cc.Vec2(pos.x, pos.y);
            if(drop)
            {
                firstDropPosition.y += FIRST_DROP_HEIGHT;
            }
            else
            {
                firstDropPosition.y -= LINE_HEIGHT;
            }
            
            this.node.position = firstDropPosition;
            this.createFirst = false;
        }
                
        this.dropTime = DROP_SPEED;
        this.targetPosition = pos;
        this.dropSpeed = (this.node.position.y - this.targetPosition.y) / this.dropTime;
        tileBtn.movingTileNum += 1;
    }

    onSetNumber = (param: any[]) =>
    {
        let number = param[2];
        this.SetNumber(number);
    }

    SetNumber(num: number)
    {
        if(this.numLabel == null)
            return;
            
        if(num == 0)
        {
            this.numLabel.string = '';
        }
        else
        {
            this.numLabel.string = num.toString();
        }
    }
}
